#include "dtwrecoge.h"

DTWRecoge::DTWRecoge()
{

}

double DTWRecoge::DTWDistanceFun(double *A, int I, double *B, int J, int r)
{
    int i, j;
    double dist;
    int istart, imax;
    int r2=r+ABS(I-J);
    double g1, g2, g3;
    int pathsig=1;

    if(I>DTWMAXNUM || J>DTWMAXNUM) {
        return -1.0;
    }

    for(i=0;i<I;i++) {
        for(j=0;j<J;j++) {
            dtwpath[i][j]=0;
            distance[i][j]=DTWVERYBIG;
        }
    }

    distance[0][0]=(double)2*ABS(A[0]-B[0]);
    for(i=1;i<=r2;i++) {
        distance[i][0]=distance[i-1][0]+ABS(A[i]-B[0]);
    }
    for(j=i;j<=r2;j++) {
        distance[0][j]=distance[0][j-1]+ABS(A[0]-B[j]);
    }

    for(j=1;j<J;j++) {
        istart=j-r2;
        if(j<=r2)
            istart=1;
        imax=j+r2;
        if(imax>=I)
            imax=I-1;

        for(i=istart;i<=imax;i++) {
            g1=distance[i-1][j]+ABS(A[i]-B[j]);
            g2=distance[i-1][j-1]+2*ABS(A[i]-B[j]);
            g3=distance[i][j-1]+ABS(A[i]-B[j]);
            g2=MIN(g1, g2);
            g3=MIN(g2, g3);
            distance[i][j]=g3;
        }
    }
    dist = distance[I-1][J-1]/((double)(I+J));
    return dist;
}

int DTWRecoge::DTWTemplate(double *A, int I, double *B, int J, double *temp, int turn, double tt, double *rltdistance)
{
    double dist;
    int i, j;
    int pathsig=1;
    dist=DTWDistanceFun(A,I,B,J,(int)(I/30));
    if(dist>tt) {
        printf("\nSample does not match!\n");
        return -1;
    }
    if(turn==1) {
        *rltdistance=dist;
    }else{
        *rltdistance=((*rltdistance)*(turn-1)+dist)/turn;
    }
    i=I-1;
    j=J-1;
    while(j>=1 || i>=1) {
        double m;
        if(i>0&&j>0) {
            m=MIN(MIN(distance[i-1][j], distance[i-1][j-1]), distance[i][j-1]);
            if(m==distance[i-1][j]) {
                dtwpath[i-1][j]=pathsig;
                i--;
            }else if(m==distance[i-1][j-1]) {
                dtwpath[i-1][j-1]=pathsig;
                i--;
                j--;
            }else{
                dtwpath[i][j-1]=pathsig;
                j--;
            }
        }else if(i==0) {
            dtwpath[0][j-1]=pathsig;
            j--;
        }else{
            dtwpath[i-1][0]=pathsig;
            i--;
        }
    }
    dtwpath[0][0]=pathsig;
    dtwpath[I-1][J-1]=pathsig;

    for(i=0;i<I;i++) {
        double ftemp=0.0;
        int ntemp=0;
        for(j=0;j<J;j++) {
            if(dtwpath[i][j]==pathsig) {
                ftemp+=B[j];
                ntemp++;
            }
        }
        ftemp/=((double)ntemp);
        temp[i]=(A[i]*turn+ftemp)/((double)(turn+1));
    }
    return I;
}
